package ansible

import (
	"fmt"
	"strings"
)

// ModuleOptions 表示模块选项
type ModuleOptions map[string]interface{}

// String 将模块选项转换为字符串
func (m ModuleOptions) String() string {
	var parts []string
	for k, v := range m {
		parts = append(parts, fmt.Sprintf("%s=%v", k, v))
	}
	return strings.Join(parts, " ")
}

// Copy 执行 copy 模块
func (a *Ansible) Copy(src, dest string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("src=%s dest=%s", src, dest)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("copy", args)
}

// File 执行 file 模块
func (a *Ansible) File(path string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("path=%s", path)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("file", args)
}

// Template 执行 template 模块
func (a *Ansible) Template(src, dest string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("src=%s dest=%s", src, dest)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("template", args)
}

// Service 执行 service 模块
func (a *Ansible) Service(name, state string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("name=%s state=%s", name, state)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("service", args)
}

// Package 执行 package 模块
func (a *Ansible) Package(name, state string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("name=%s state=%s", name, state)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("package", args)
}

// Yum 执行 yum 模块
func (a *Ansible) Yum(name, state string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("name=%s state=%s", name, state)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("yum", args)
}

// Apt 执行 apt 模块
func (a *Ansible) Apt(name, state string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("name=%s state=%s", name, state)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("apt", args)
}

// User 执行 user 模块
func (a *Ansible) User(name string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("name=%s", name)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("user", args)
}

// Group 执行 group 模块
func (a *Ansible) Group(name string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("name=%s", name)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("group", args)
}

// Mount 执行 mount 模块
func (a *Ansible) Mount(path, src, fstype string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("path=%s src=%s fstype=%s", path, src, fstype)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("mount", args)
}

// Cron 执行 cron 模块
func (a *Ansible) Cron(name, job string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("name='%s' job='%s'", name, job)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("cron", args)
}

// Git 执行 git 模块
func (a *Ansible) Git(repo, dest string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("repo=%s dest=%s", repo, dest)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("git", args)
}

// Lineinfile 执行 lineinfile 模块
func (a *Ansible) Lineinfile(path, line string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("path=%s line='%s'", path, line)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("lineinfile", args)
}

// Replace 执行 replace 模块
func (a *Ansible) Replace(path, regexp, replace string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("path=%s regexp='%s' replace='%s'", path, regexp, replace)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("replace", args)
}

// Fetch 执行 fetch 模块
func (a *Ansible) Fetch(src, dest string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("src=%s dest=%s", src, dest)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("fetch", args)
}

// Synchronize 执行 synchronize 模块
func (a *Ansible) Synchronize(src, dest string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("src=%s dest=%s", src, dest)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("synchronize", args)
}

// Uri 执行 uri 模块
func (a *Ansible) Uri(url string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("url=%s", url)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("uri", args)
}

// Wait_for 执行 wait_for 模块
func (a *Ansible) WaitFor(options ModuleOptions) ([]byte, []byte, error) {
	return a.RunWithModule("wait_for", options.String())
}

// Setup 执行 setup 模块（收集系统信息）
func (a *Ansible) Setup(options ...ModuleOptions) ([]byte, []byte, error) {
	if len(options) > 0 {
		return a.RunWithModule("setup", options[0].String())
	}
	return a.RunWithModule("setup")
}

// Debug 执行 debug 模块
func (a *Ansible) Debug(options ModuleOptions) ([]byte, []byte, error) {
	return a.RunWithModule("debug", options.String())
}

// Fail 执行 fail 模块
func (a *Ansible) Fail(msg string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("msg='%s'", msg)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("fail", args)
}

// Assert 执行 assert 模块
func (a *Ansible) Assert(that string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("that=%s", that)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("assert", args)
}

// Include_vars 执行 include_vars 模块
func (a *Ansible) IncludeVars(file string, options ...ModuleOptions) ([]byte, []byte, error) {
	args := fmt.Sprintf("file=%s", file)
	if len(options) > 0 {
		args += " " + options[0].String()
	}
	return a.RunWithModule("include_vars", args)
}

// Set_fact 执行 set_fact 模块
func (a *Ansible) SetFact(facts ModuleOptions) ([]byte, []byte, error) {
	return a.RunWithModule("set_fact", facts.String())
}
